<?php

declare(strict_types=1);

namespace Core\System;

use function Hyperf\Config\config;
use Hyperf\HttpServer\Router\DispatcherFactory;
use Hyperf\Server\ServerInterface;
use JetBrains\PhpStorm\ArrayShape;

class RouteUnit
{


    /**
     * 返回路由详情
     * @param string $route
     * @return array|null
     */
    public static function getRouteInfo(string $route): ?array
    {
        return self::getRouteAll()[$route] ?? null;
    }


    /**
     * 获取全部路由信息,过滤回调函数路由
     * @param string|null $serName
     * @return array
     */
    public static function getRouteAll(?string $serName = null): array
    {
        $dispatcher = container(DispatcherFactory::class);
        $routeList = [];
        foreach (config('server.servers') as $server) {
            if ($server['type'] != ServerInterface::SERVER_HTTP) {
                continue;//只获取HTTP服务的内容
            }
            if ($serName === null || $serName === $server['name']) {
                $serverName = $server['name'];
                [$staticRouters] = $dispatcher->getRouter($serverName)->getData();
                foreach ($staticRouters as $method => $routers) {
                    foreach ($routers as $router => $routersInfo) {
                        $callback = $routersInfo->callback;
                        if (is_array($callback)) {
                            if (empty($routeList[$router])) {
                                $routeList[$router] = ['server' => $serverName, 'router' => $router, 'method' => [], 'callback' => $callback];
                            }
                            $routeList[$router]['method'][] = $method;
                        }
                    }
                }
            }
        }
        return $routeList;
    }


    /**
     * 按控制器和方法获取路由信息
     * @param string $class
     * @param string $action
     * @return array|null
     */
    #[ArrayShape(['server' => 'string', 'router' => 'string', 'method' => 'array', 'callback' => 'array'])]
    public static function getActionRoute(string $class, string $action): ?array
    {
        foreach (self::getRouteAll() as $item) {
            if (isset($item['callback'][0]) && isset($item['callback'][1])) {
                if ($item['callback'][0] === $class && $item['callback'][1] === $action) {
                    return $item;
                }
            }
        }
        return null;
    }
}